package com.dahua.demo.util;

import com.dahua.demo.login.Login;
import com.google.gson.Gson;
import org.apache.http.client.methods.*;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.*;
import java.io.*;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

public class HttpTestUtils {



    public static String httpRequest(HttpEnum method,String ip, int port, String action, String token, String content) {
        String responJson = null;
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        InputStream inputStream = null;
        KeyStore trustStore = null;
        SSLContext sslcontext = null;
        try {
            trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            // 设置信任签名
            sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            }).build();
            X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
                @Override
                public void verify(String s, SSLSocket sslSocket) throws IOException {

                }

                @Override
                public void verify(String s, X509Certificate x509Certificate) throws SSLException {

                }

                @Override
                public void verify(String s, String[] strings, String[] strings1) throws SSLException {

                }

                @Override
                public boolean verify(String s, SSLSession sslSession) {
                    return true;
                }
            };
            // 设置协议http和https对应的处理socket链接工厂的对象
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.INSTANCE)
                    .register("https", new SSLConnectionSocketFactory(sslcontext, hostnameVerifier))
                    .build();

            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

            httpClient = HttpClientBuilder.create()
                    .setConnectionManager(connectionManager)
                    .setRedirectStrategy(new RestRedirectStrategy()).build();
            String proto = port == 8320 ? "https://" : "http://";
            String uri= proto + ip + ":" + port + action;
            HttpRequestBase httpReq = getRequestEntity(method, token, uri, content);
            httpResponse = httpClient.execute(httpReq);
            inputStream = httpResponse.getEntity().getContent();
            responJson = convertToString(inputStream);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return responJson;
    }

    private static HttpRequestBase getRequestEntity(HttpEnum method, String token, String uri, String content) throws UnsupportedEncodingException {
        switch(method.getNum()){
            case 1:
                HttpGet httpGet = new HttpGet(uri+content);
                httpGet.addHeader("Content-type", "application/json");
                httpGet.addHeader("X-Subject-Token", token);
                return httpGet;
            case 2:
                HttpPost httpPost = new HttpPost(uri);
                httpPost.addHeader("Content-type", "application/json");
                httpPost.addHeader("X-Subject-Token", token);
                httpPost.setEntity(new StringEntity(content,"UTF-8"));
                return httpPost;
            case 3:
                HttpPut httpPut= new HttpPut(uri);
                httpPut.addHeader("Content-type", "application/json");
                httpPut.addHeader("X-Subject-Token", token);
                httpPut.setEntity(new StringEntity(content,"UTF-8"));
                return httpPut;
            case 4:
                HttpDelete httpDelete = new HttpDelete(uri+content);
                httpDelete.addHeader("Content-type", "application/json");
                httpDelete.addHeader("X-Subject-Token", token);
                return httpDelete;
            default:
                    System.out.println("请求方法不对");
        }
        return null;
    }

    private static String convertToString(InputStream is) {
        if (is == null) {
            return null;
        }
        BufferedReader bf = null;
        try {
            StringBuilder sb = new StringBuilder();
            String temp = "";
            bf = new BufferedReader(new InputStreamReader(is,"UTF-8"));
            while ((temp = bf.readLine()) != null) {
                sb.append(temp);
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            closeStream(bf);
            closeStream(is);
        }
    }

    private static void closeStream(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static String getToken(String ip,int port,String userName,String password) throws Exception {
        String response="";
        String token="";
        response = Login.login(ip, port, userName, password);
        Map<String, Object> rsp = new Gson().fromJson(response, Map.class);
        String message= (String)rsp.get("message");
        if (message!=null&&!"".equals(message)){
            System.out.println(message);
            throw new Exception("未获取到token");
        }
        token = (String)rsp.get("token");
        if(token==null||"".equals(token)){
            System.out.println("获取到的token为空");
            throw new Exception("获取到的token为空");
        }
        return  token;
    }

}
